using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using GRPCDemo.Protocol;

namespace Common.NetWork
{
    public class PackageHelper : PackageHelper<object>
    {
        public PackageHelper(object sender) : base(sender)
        {
        }
    }

    public class PackageHelper<T>
    {
        private T sender;

        private MemoryStream stream = new MemoryStream(64 * 1024);

        public PackageHelper(T sender)
        {
            this.sender = sender;
        }

        public void ReceiveData(byte[] data, int offset, int count)
        {
            if (stream.Position + count > stream.Capacity)
            {
                throw new Exception("PackageHandler write buffer overflow");
            }
            stream.Write(data, offset, count);


            ParsePackage();
        }

        public static byte[] PackMessage(NetMessage message)
        {
            byte[] package = null;
            using (MemoryStream ms = new MemoryStream())
            {
                ProtoBuf.Serializer.Serialize(ms, message);
                //package = new byte[ms.Length + 4];
                //Buffer.BlockCopy(BitConverter.GetBytes(ms.Length), 0, package, 0, 4);
                //Buffer.BlockCopy(ms.GetBuffer(), 0, package, 4, (int)ms.Length);
                package = new byte[ms.Length];
                Buffer.BlockCopy(ms.GetBuffer(), 0, package, 0, (int)ms.Length);
            }
            return package;
        }

        public static NetMessage UnPackMessage(byte[] packet, int offset, int length)
        {
            NetMessage message = null;
            using (MemoryStream ms = new MemoryStream(packet, offset, length))
            {
                message = ProtoBuf.Serializer.Deserialize<NetMessage>(ms);
            }
            return message;
        }

        void ParsePackage()
        {
            var message = UnPackMessage(stream.GetBuffer(), 0, (int)stream.Position);

            MessageDistributer<T>.Instance.ReceiveMessage(sender, message);

            stream.Position = 0;
        }
    }
}
